home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / fp_adpcm / adpcm_dt / source / dispatch2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1980-01-03  |  5.7 KB  |  243 lines

  1.  
  2. /*
  3.  * ADPCMx Decrunch : sound datatype
  4.  *
  5.  */
  6.  
  7. #include "classbase.h"
  8.  
  9. #define TARGET_SIZE 16384
  10.  
  11. extern __asm ULONG DecompressADPCM2(    register __a0 UBYTE *Source,
  12.                     register __d0 ULONG Length,
  13.                     register __a1 UBYTE *Destination,
  14.                     register __d1 ULONG JoinCode    );
  15.  
  16. extern __asm ULONG DecompressADPCM3(    register __a0 UBYTE *Source,
  17.                     register __d0 ULONG Length,
  18.                     register __a1 UBYTE *Destination,
  19.                     register __d1 ULONG JoinCode    );
  20. #define    DB(x)    
  21.  
  22. Class *initClass (struct ClassBase * cb)
  23. {
  24.     Class *cl;
  25.     
  26.     if (cl = MakeClass (LibName, SOUNDDTCLASS, NULL, NULL, 0L))
  27.     {
  28.         cl->cl_Dispatcher.h_Entry = (ULONG (*)())Dispatch;
  29.         cl->cl_UserData = (ULONG) cb;
  30.         AddClass (cl);
  31.     }
  32.     
  33.     return (cl);
  34. }
  35.  
  36.  
  37. ULONG __asm Dispatch (register __a0 Class * cl,
  38.               register __a2 Object * o,
  39.               register __a1 Msg msg)
  40. {
  41.     struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  42.     ULONG retval = 0L;
  43.     
  44.     switch (msg->MethodID)
  45.     {
  46.     case OM_NEW:
  47.         if (retval = DoSuperMethodA (cl, o, msg))
  48.         {
  49.         if (!(ConvertObjectData (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList)))
  50.             {
  51.             CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
  52.             retval = NULL;
  53.             }
  54.         }
  55.         break;
  56.         
  57.      /* Let the superclass handle everything else */
  58.     
  59.     default:
  60.         retval = (ULONG) DoSuperMethodA (cl, o, msg);
  61.         break;
  62.     }
  63.     return (retval);
  64. }
  65.  
  66. struct ADPCMHeader
  67. {
  68.     UBYTE Identifier[6];        /* $00 */
  69.     ULONG Frequency;        /* $06 */
  70. };
  71.  
  72. /*****************************************************************************/
  73.  
  74. BOOL ConvertObjectData (struct ClassBase * cb,
  75.             Class * cl,
  76.             Object * o,
  77.             struct TagItem * attrs)
  78. {
  79.     struct FileInfoBlock *fib;
  80.     struct VoiceHeader *vhdr;
  81.     struct ADPCMHeader ADPCMHeader;
  82.     STRPTR Title;
  83.     BPTR FH;
  84.     LONG ErrorCode=0;
  85.     ULONG Memory;
  86.     ULONG Size;
  87.     ULONG SampleSize;
  88.     UBYTE *Sample;
  89.     
  90.     Title = (STRPTR) GetTagData (DTA_Name, NULL, attrs);
  91.     
  92.     getdtattrs (cb, o,
  93.         SDTA_VoiceHeader, &vhdr,
  94.         DTA_Handle, &FH,
  95.         TAG_DONE);
  96.     
  97.     if (FH && vhdr)
  98.     {
  99.         /* Allocate a temporary file info block */
  100.         if (!(fib = (struct FileInfoBlock *) AllocMem (sizeof (struct FileInfoBlock), NULL)))
  101.         {
  102.             ErrorCode=ERROR_NO_FREE_STORE;
  103.         }
  104.         else
  105.         {
  106.             /* Get the size of the file */
  107.             if (ExamineFH (FH, fib))
  108.             {
  109.                 Size = fib->fib_Size;
  110.             }
  111.             else
  112.             {
  113.                 Seek (FH, 0, OFFSET_END);
  114.                 Size = Seek (FH, 0, OFFSET_BEGINNING);
  115.             }
  116.             
  117.             /* Free the temporary file info block */
  118.             FreeMem (fib, sizeof (struct FileInfoBlock));
  119.             
  120.             /* Calculate size from actual file length */
  121.             Size-=sizeof(struct ADPCMHeader);
  122.             
  123.             /* Read in sample header */
  124.             if (Read(FH,&ADPCMHeader,sizeof(struct ADPCMHeader))==sizeof(struct ADPCMHeader))
  125.             {
  126.                 /* Check if it is a supported ADPCM format */
  127.                 if (ADPCMHeader.Identifier[5] != '2' && ADPCMHeader.Identifier[5] != '3')
  128.                 {
  129.                     ErrorCode=ERROR_OBJECT_WRONG_TYPE;
  130.                 }
  131.                 else
  132.                 {
  133.                     ULONG Bits;
  134.                     
  135.                     /* Retrieve the number of compression bits */
  136.                     if (ADPCMHeader.Identifier[5] == '2') Bits=2;
  137.                     if (ADPCMHeader.Identifier[5] == '3') Bits=3;
  138.                     
  139.                     /* Calculate the real sample size */
  140.                     if (Bits==2) SampleSize=Size*4 ;
  141.                     if (Bits==3) SampleSize=Size*8/3;
  142.                     
  143.                     /* sound.datatype V40 can replay */
  144.                     /* directly from Fast RAM */
  145.                     
  146.                     Memory = (SuperClassBase->lib_Version>39) ?
  147.                                 MEMF_ANY : MEMF_CHIP;
  148.                     
  149.                     /* Allocate a buffer with the calculated size */
  150.                     if (!(Sample=AllocVec(SampleSize,Memory)))
  151.                     {
  152.                         ErrorCode=ERROR_NO_FREE_STORE;
  153.                     }
  154.                     else
  155.                     {
  156.                         UBYTE *ADPCMBuffer;
  157.                         ULONG ADPCMSize;
  158.                         
  159.                         if (Bits==2) ADPCMSize=(TARGET_SIZE+3)/4;
  160.                         if (Bits==3) ADPCMSize=(TARGET_SIZE+7)/8*3;
  161.                         
  162.                         if (ADPCMBuffer=AllocVec(ADPCMSize, MEMF_ANY))
  163.                         {
  164.                             ULONG Position,SampleOffset;
  165.                             ULONG JoinCode=0;
  166.                             
  167.                             for (Position=0,SampleOffset=0; Position<Size; )
  168.                             {
  169.                                 ULONG Left=Size-Position;
  170.                                 ULONG Do = Left < ADPCMSize ?
  171.                                            Left : ADPCMSize ;
  172.                                 LONG Got;
  173.                                 
  174.                                 if (Got=Read(FH, ADPCMBuffer, Do) != Do)
  175.                                 {
  176.                                     if (Got<0) ErrorCode=IoErr();
  177.                                     else ErrorCode=ERROR_BAD_HUNK;
  178.                                     break;
  179.                                 }
  180.                                 
  181.                                 if (Bits==2) JoinCode=DecompressADPCM2(ADPCMBuffer, Do, Sample+SampleOffset, JoinCode);
  182.                                 if (Bits==3) JoinCode=DecompressADPCM3(ADPCMBuffer, Do, Sample+SampleOffset, JoinCode);
  183.                                 
  184.                                 Position+=Do;
  185.                                 
  186.                                 if (Bits==2) SampleOffset+=Do*4;
  187.                                 if (Bits==3) SampleOffset+=Do*8/3;
  188.                             }
  189.                             
  190.                             if (!ErrorCode)
  191.                             {
  192.                                 /* Fill in the VoiceHeader */
  193.                                 memset(vhdr,0,sizeof(struct VoiceHeader));
  194.                                 vhdr->vh_OneShotHiSamples= Size;
  195.                                 vhdr->vh_SamplesPerSec    = ADPCMHeader.Frequency;
  196.                                 vhdr->vh_Octaves    = 1;
  197.                                 vhdr->vh_Compression    = CMP_NONE;
  198.                                 vhdr->vh_Volume        = 64;
  199.                                 
  200.                                 /* Tell the super-class about the attributes */
  201.                                 setdtattrs (cb, o,
  202.                                     DTA_ObjName,    Title,
  203.                                     SDTA_Sample,    Sample,
  204.                                     SDTA_SampleLength,SampleSize,
  205.                                     SDTA_Period,    (ULONG)(SysBase->ex_EClockFrequency*5)/(ULONG)vhdr->vh_SamplesPerSec,
  206.                                     SDTA_Volume,    64,
  207.                                     SDTA_Cycles,    1,
  208.                                     TAG_DONE);
  209.                             }
  210.                             else
  211.                             {
  212.                                 FreeVec(Sample);
  213.                             }
  214.                             FreeVec(ADPCMBuffer);
  215.                         }
  216.                     }
  217.                 }
  218.             }
  219.         }
  220.     }
  221.     if (ErrorCode)
  222.     {
  223.         SetIoErr(ErrorCode);
  224.         return(FALSE);
  225.     }
  226.     return(TRUE);
  227. }
  228.  
  229.  
  230. /*****************************************************************************/
  231.  
  232. ULONG setdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
  233. {
  234.     return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
  235. }
  236.  
  237. /*****************************************************************************/
  238.  
  239. ULONG getdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
  240. {
  241.     return (GetDTAttrsA (o, (struct TagItem *) & data));
  242. }
  243.